package com.leadingsoft.pwxk.service.impl;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.persistence.EntityManager;

import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.leadingsoft.common.exception.DataValidateException;
import com.leadingsoft.pwxk.dto.SearchDto;
import com.leadingsoft.pwxk.enums.MonthEnum;
import com.leadingsoft.pwxk.enums.RiverBasinEnum;
import com.leadingsoft.pwxk.enums.StatisticalEnum;
import com.leadingsoft.pwxk.model.Category;
import com.leadingsoft.pwxk.model.QBaseInfo;
import com.leadingsoft.pwxk.model.QLatestData;
import com.leadingsoft.pwxk.model.QLicenseInfo;
import com.leadingsoft.pwxk.model.QPwBaseInfo;
import com.leadingsoft.pwxk.model.QRegionCode;
import com.leadingsoft.pwxk.model.QYearPlan;
import com.leadingsoft.pwxk.model.RiverBasinRegionRelation;
import com.leadingsoft.pwxk.repository.CategoryRepository;
import com.leadingsoft.pwxk.repository.RiverBasinRegionRelationRepository;
import com.leadingsoft.pwxk.service.CategoryService;
import com.leadingsoft.pwxk.service.LIIStatisticalService;
import com.querydsl.core.Tuple;
import com.querydsl.jpa.impl.JPAQuery;

import lombok.extern.slf4j.Slf4j;

/**
 * 
 * @author ysh
 * @desc 排污许可证发放量统计-服务类
 */
@Slf4j
@Service
public class LIIStatisticalServiceImpl implements LIIStatisticalService {

	QLicenseInfo qLicenseInfo = QLicenseInfo.licenseInfo;

	QBaseInfo qBaseInfo = QBaseInfo.baseInfo;

	QPwBaseInfo qPwBaseInfo = QPwBaseInfo.pwBaseInfo;

	QYearPlan qYearPlan = QYearPlan.yearPlan;

	QRegionCode qRegionCode = QRegionCode.regionCode1;

	QLatestData qLatestData = QLatestData.latestData;

	@Autowired
	private EntityManager em;

	@Autowired
	CategoryRepository categoryRepository;

	@Autowired
	CategoryService categoryService;

	@Autowired
	RiverBasinRegionRelationRepository riverBasinRegionRelationRepository;

	@Override
	public List<Map<String, Object>> getStatistical(SearchDto s) {
		List<Map<String, Object>> list = new ArrayList<Map<String, Object>>();
		JPAQuery<Tuple> query = new JPAQuery<Tuple>(em);
		bulidFilterBox(s, query);
		switch (s.getStatisticalEnum()) {
		case AREA:
			return getAreaStatistical(s, list, query);
		case INDUSTRY:
			return getIndustryStatistical(s, list);
		case RIVER_BASIN:
			return getRiverBasinStatistical(s, list, query);
		case YEAR:
			getYearStatistical(s, list, query);
			break;
		case ISSUED:
			return getIssuedStatistical(s, list);
		default:
			throw new DataValidateException("统计枚举参数异常");
		}
		log.info("---" + s.getStatisticalEnum().getDesc());
		List<Tuple> fetch = query.fetch();
		log.info("--" + fetch);
		if (s.getStatisticalEnum() == StatisticalEnum.YEAR && StringUtils.isNotBlank(s.getYear())) {
			fetch.forEach(t -> {
				Map<String, Object> map = new HashMap<String, Object>();
				map.put("num", t.get(0, Integer.class));
				map.put("name", t.get(1, String.class) + "月");
				list.add(map);
			});
			for (MonthEnum value : MonthEnum.values()) {
				boolean flag = false;
				for (Map<String, Object> val : list) {
					if (val.get("name").equals(value.getDesc())) {
						flag = true;
						break;
					}
				}
				if (!flag) {
					Map<String, Object> map = new HashMap<String, Object>();
					map.put("num", 0);
					map.put("name", value.getDesc());
					list.add(map);
				}
			}
			// 排序
			List<Map<String, Object>> re = new ArrayList<Map<String, Object>>();
			for (MonthEnum value : MonthEnum.values()) {
				for (Map<String, Object> val : list) {
					if (val.get("name").equals(value.getDesc())) {
						re.add(val);
						break;
					}
				}
			}
			return re;
		} else {
			fetch.forEach(t -> {
				Map<String, Object> map = new HashMap<String, Object>();
				map.put("num", t.get(0, Integer.class));
				map.put("name", t.get(1, String.class));
				list.add(map);
			});
		}
		return list;
	}

	private void bulidFilterBox(SearchDto s, JPAQuery<Tuple> query) {
		if (StringUtils.isNotBlank(s.getCodeRegion())) {
			query.where(qBaseInfo.code_region.eq(s.getCodeRegion()));
		}
		if (StringUtils.isNotBlank(s.getYear())) {
			query.where(qLicenseInfo.fztime.substring(0, qLicenseInfo.fztime.indexOf("-")).eq(s.getYear()));
		}
		if (null == s.getStatisticalEnum()) {
			throw new DataValidateException("统计枚举参数异常");
		}
	}

	private List<Map<String, Object>> getAreaStatistical(SearchDto s, List<Map<String, Object>> list, JPAQuery<Tuple> query) {
		if (StringUtils.isNotBlank(s.getCodeRegion())) {
			query.select(qBaseInfo.enterid, qBaseInfo.name_regiondetail, qBaseInfo.code_regiondetail);
			query.orderBy(qBaseInfo.code_regiondetail.asc());
		} else {
			query.select(qBaseInfo.enterid, qBaseInfo.name_region, qBaseInfo.code_region);
			query.orderBy(qBaseInfo.code_region.asc());
		}
		query.from(qLatestData).leftJoin(qLicenseInfo).on(qLatestData.dataid.eq(qLicenseInfo.dataid));
		query.leftJoin(qPwBaseInfo).on(qLicenseInfo.dataid.eq(qPwBaseInfo.dataid)).leftJoin(qBaseInfo)
				.on(qBaseInfo.enterid.eq(qPwBaseInfo.enterid));
		List<Tuple> fetch = query.fetch();
		Map<String, String> distinctMap = new LinkedHashMap<String, String>();
		Set<String> nameSet = new LinkedHashSet<String>();
		fetch.forEach(t -> {
			distinctMap.put(t.get(0, String.class), t.get(1, String.class));
			nameSet.add(t.get(1, String.class));
		});
		List<Map<String, Object>> result = new ArrayList<Map<String,Object>>();
		int count;
		for (String name : nameSet) {
			count = 0;
			for (String val : distinctMap.values()) {
				if (name.equals(val)) {
					count++;
				}
			}
			Map<String, Object> map = new HashMap<String, Object>();
			map.put("name", name);
			map.put("num", count);
			result.add(map);
		}
		return result;
	}

	private List<Map<String, Object>> getIndustryStatistical(SearchDto s, List<Map<String, Object>> list) {
		List<Category> all = categoryRepository.findAll();
		List<Category> root = new ArrayList<Category>(64);
		if (StringUtils.isBlank(s.getHyid())) {
			all.forEach(t -> {
				if (StringUtils.isBlank(t.getParentCode())) {
					root.add(t);
				}
			});
		} else {
			Category category = categoryRepository.findByCode(s.getHyid());
			all.forEach(t -> {
				if (null != t.getParentCode() && t.getParentCode().equals(category.getCode())) {
					root.add(t);
				}
			});
		}
		List<Map<String, Object>> result = new ArrayList<Map<String, Object>>();
		root.forEach(t -> {
			JPAQuery<Tuple> query = new JPAQuery<Tuple>(em);
			bulidFilterBox(s, query);
			List<String> childCodes = new ArrayList<String>(64);
			categoryService.getChildCode(t, all, childCodes);
			query.select(qPwBaseInfo.hyid.count());
			query.from(qLatestData).leftJoin(qLicenseInfo).on(qLatestData.dataid.eq(qLicenseInfo.dataid));
			query.leftJoin(qPwBaseInfo).on(qLicenseInfo.dataid.eq(qPwBaseInfo.dataid)).leftJoin(qBaseInfo)
					.on(qBaseInfo.enterid.eq(qPwBaseInfo.enterid));
			query.where(qPwBaseInfo.hyid.in(childCodes));
			// query.groupBy(qPwBaseInfo.hyname);
			// query.orderBy(qPwBaseInfo.qthyid.asc());
			List<Tuple> fetch = query.fetch();
			Map<String, Object> tempMap = new HashMap<String, Object>();
			tempMap.put("name", t.getName());
			tempMap.put("num", fetch.get(0));
			result.add(tempMap);
		});
		return result;
	}

	private List<Map<String, Object>> getRiverBasinStatistical(SearchDto s, List<Map<String, Object>> list,
			JPAQuery<Tuple> query) {
		List<Map<String, Object>> result = new ArrayList<Map<String, Object>>();
		query.select(qBaseInfo.name_region, qBaseInfo.name_regiondetail);
		query.from(qLatestData).leftJoin(qLicenseInfo).on(qLatestData.dataid.eq(qLicenseInfo.dataid));
		query.leftJoin(qPwBaseInfo).on(qLicenseInfo.dataid.eq(qPwBaseInfo.dataid)).leftJoin(qBaseInfo)
				.on(qBaseInfo.enterid.eq(qPwBaseInfo.enterid));
		List<Tuple> fetch = query.fetch();
		List<RiverBasinRegionRelation> rbs = riverBasinRegionRelationRepository.findAll();
		Map<String, List<RiverBasinRegionRelation>> allMap = new LinkedHashMap<String, List<RiverBasinRegionRelation>>();
		for (RiverBasinEnum e : RiverBasinEnum.values()) {
			List<RiverBasinRegionRelation> temp = new ArrayList<RiverBasinRegionRelation>();
			rbs.forEach(t -> {
				if (t.getRiverBasinName().equals(e.getVal())) {
					temp.add(t);
				}
			});
			log.info(e.getVal() + "->");
			allMap.put(e.getVal(), temp);
		}
		allMap.forEach((key, val) -> {
			Integer num = 0;
			for (RiverBasinRegionRelation v : val) {
				for (Tuple t : fetch) {
					if (v.getRegionName().indexOf(t.get(qBaseInfo.name_region)) != -1
							&& v.getRegionDetailName().indexOf(t.get(qBaseInfo.name_regiondetail)) != -1) {
						num++;
					}

				}
			}
			Map<String, Object> tempMap = new LinkedHashMap<String, Object>();
			tempMap.put("name", key);
			tempMap.put("num", num);
			result.add(tempMap);
		});

		return result;
	}

	private void getYearStatistical(SearchDto s, List<Map<String, Object>> list, JPAQuery<Tuple> query) {
		if (StringUtils.isNotBlank(s.getYear())) {
			query.select(qLicenseInfo.dataid.count(), qLicenseInfo.fztime.substring(5, 7));
			query.from(qLatestData).leftJoin(qLicenseInfo).on(qLatestData.dataid.eq(qLicenseInfo.dataid));
			query.leftJoin(qPwBaseInfo).on(qLicenseInfo.dataid.eq(qPwBaseInfo.dataid));
			query.groupBy(qLicenseInfo.fztime.substring(5, 7));
			query.orderBy(qLicenseInfo.fztime.substring(5, 7).asc());
		} else {
			query.select(qLicenseInfo.dataid.count(), qLicenseInfo.fztime.substring(0, 4));
			query.from(qLatestData).leftJoin(qLicenseInfo).on(qLatestData.dataid.eq(qLicenseInfo.dataid));
			query.leftJoin(qPwBaseInfo).on(qLicenseInfo.dataid.eq(qPwBaseInfo.dataid));
			query.groupBy(qLicenseInfo.fztime.substring(0, 4));
		}
	}

	private List<Map<String, Object>> getIssuedStatistical(SearchDto s, List<Map<String, Object>> list) {
		JPAQuery<Tuple> query = new JPAQuery<Tuple>(em);
		query.select(qYearPlan.id.count(), qYearPlan.regionName, qRegionCode.regionCode);
		query.from(qYearPlan).leftJoin(qRegionCode).on(qYearPlan.regionName.eq(qRegionCode.regionName));
		if (StringUtils.isNoneBlank(s.getYear())) {
			query.where(qYearPlan.year.eq(s.getYear()));
		}
		query.groupBy(qYearPlan.regionName, qRegionCode.regionCode);
		query.orderBy(qRegionCode.regionCode.asc());
		JPAQuery<Tuple> query2 = new JPAQuery<Tuple>(em);
		query2.select(qBaseInfo.id.count(), qBaseInfo.name_region);
		query2.from(qLatestData).leftJoin(qLicenseInfo).on(qLatestData.dataid.eq(qLicenseInfo.dataid));
		query2.leftJoin(qPwBaseInfo).on(qLicenseInfo.dataid.eq(qPwBaseInfo.dataid)).leftJoin(qBaseInfo)
				.on(qBaseInfo.enterid.eq(qPwBaseInfo.enterid));
		if (StringUtils.isNoneBlank(s.getYear())) {
			query2.where(qLicenseInfo.fztime.substring(0, qLicenseInfo.fztime.indexOf("-")).eq(s.getYear()));
		}
		query2.groupBy(qBaseInfo.name_region);
		List<Tuple> fetch = query.fetch();
		List<Tuple> fetch2 = query2.fetch();
		fetch.forEach(t -> {
			Map<String, Object> map = new HashMap<String, Object>();
			map.put("sf", 0);
			fetch2.forEach(t2 -> {
				if (t.get(qYearPlan.regionName).equals(t2.get(qBaseInfo.name_region))) {
					map.put("sf", t2.get(qBaseInfo.id.count()));
				}
			});
			map.put("key", t.get(qYearPlan.regionName));
			map.put("hf", t.get(qYearPlan.id.count()));
			list.add(map);
		});
		return list;
	}

}
